<?php
/**
 * Created by PhpStorm.
 * User: hb@wsd
 * Date: 17-12-25
 * Time: 下午10:54
 */

namespace app\Route;

use Server\CoreBase\XssClean;
use Server\Route\NormalRoute;

class JsonRpcRoute extends NormalRoute
{
    private $wsd_client_data;

    public function __construct()
    {
        $this->wsd_client_data = new \stdClass();
        $this->wsd_client_data->controller_name = "";
        $this->wsd_client_data->method_name = "";
        $this->wsd_client_data->params = "";

        $this->wsd_client_data->batch = [];
    }

    /**
     * 设置反序列化后的数据 Object
     * @param $data
     * @return \stdClass
     * @throws SwooleException
     */
    public function handleClientData($data)
    {
        $this->wsd_client_data = $data;
        if (isset($this->wsd_client_data->controller_name) && isset($this->wsd_client_data->method_name)) {
            return $this->wsd_client_data;
        } else {
            throw new SwooleException('route 数据缺少必要字段');
        }

    }

    /**
     * 处理 JsonRPC over http request
     * @param $request
     */
    public function handleClientRequest($request)
    {
        $this->wsd_client_data->path = $request->server['path_info'];
        $route = explode('/', $request->server['path_info']);
        unset($route[0]);
        $this->wsd_client_data->controller_name = implode("\\", $route);

        $res = $request->rawContent();
        $resJson = $this->xss(json_decode($res,true));

        // Modify by hb on 2018-04-10 for Support JsonRPC-Batch
        /*
        if( !empty($resJson) ){
            if(isset($resJson->jsonrpc) && isset($resJson->method)){
                $this->wsd_client_data->method_name = $resJson->method;
            }
            $this->wsd_client_data->params = array(0=>$resJson->params);
            // Add by hb on 2016-12-26: 设置rpc-request-id
            $request->header['rpc_request_id'] = $resJson->id;
        }
        */

        if ( !empty($resJson) ) {
            if ( isset($resJson['jsonrpc']) ) {     // 单处理
                $this->wsd_client_data->method_name = $resJson['method'];
                $this->wsd_client_data->params = array(0=>$resJson['params']);
                $request->header['rpc_request_id'] = $resJson['id'];
            } elseif ( is_array($resJson) ) {       // 批处理
                $this->wsd_client_data->method_name = '__batchRPC';
                $this->wsd_client_data->params = array(0=>$resJson);
                $request->header['rpc_request_id'] = 0;
            }
        }
    }

    /**
     * 获取控制器名称
     * @return string
     */
    public function getControllerName()
    {
        return $this->wsd_client_data->controller_name;
    }

    /**
     * 获取方法名称
     * @return string
     */
    public function getMethodName()
    {
        return $this->wsd_client_data->method_name;
    }

    public function getPath()
    {
        return $this->wsd_client_data->path ?? "";
    }

    public function getParams()
    {
        return $this->wsd_client_data->params??null;
    }

    public function errorHandle(\Exception $e, $fd)
    {
        get_instance()->send($fd, "Error:" . $e->getMessage(), true);
        get_instance()->close($fd);
    }

    public function errorHttpHandle(\Exception $e, $request, $response)
    {
        $data = array("id"=>1, "jsonrpc"=>"2.0", "error"=>array(
            "err_code"=>404,
            "err_msg"=>'不存在的请求处理'
        ));
        $json_data = json_encode($data);
        $response->header("Content-Type", "application/json");
        $response->end($json_data);
    }

    /**
     * 对数据进行过滤
     * @param $sorAr
     * @return object $sorAr
     */
    function xss($sorAr){
        if(empty($sorAr)) return;
        foreach($sorAr as $key=>$value){
            XssClean::getXssClean($key);
            if(is_array($value)){
                foreach($value as $k=>$v){
                    XssClean::getXssClean($k);
                    XssClean::getXssClean($v);
                }
            }else{
                XssClean::getXssClean($value);
            }
        }
        // Modify by hb on 2018-04-10 for Support JsonRPC-Batch
        //return (object) $sorAr;
        return $sorAr;
    }

}